﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DDD;
using Xunit;

namespace DokiDokiTest {
    public class TestAppearance {
        [Fact]
        public void Test_New1 () {
            var app = new Appearance ();

            Assert.Equal (null, app.ShaderProgram);
            Assert.Equal (null, app.Material);
            Assert.Equal (0, app.UniformArrayCount);
            Assert.Equal (0, app.SamplerCount);
            Assert.Equal (null, app.PolygonMode);
            Assert.Equal (null, app.CompositeMode);
            Assert.Equal (null, app.PointSpriteMode);
        }

        /// <summary>
        /// Appearance, Material, CompositeMode, PolygonMode, PointSpriteModeのSet()のテスト
        /// </summary>
        [Fact]
        public void Test_Set () {
            var app = new Appearance ();
            var mat = new Material ();
            var cmode = new CompositeMode ();
            var pmode = new PolygonMode ();
            var psmode = new PointSpriteMode ();

            app.SetMaterial (mat);
            app.SetComositeMode (cmode);
            app.SetPointSpriteMode (psmode);
            app.SetPolygonMode (pmode);

            Assert.Equal (mat, app.Material);
            Assert.Equal (pmode, app.PolygonMode);
            Assert.Equal (cmode, app.CompositeMode);
            Assert.Equal (psmode, app.PointSpriteMode);
        }

        [Fact]
        public void Test_AddUniformArray () {
            var app = new Appearance ();
            var uarry1 = new UniformArray ();
            var uarry2 = new UniformArray ();

            app.AddUniformArray (uarry1);
            app.AddUniformArray (uarry2);

            Assert.Equal (2, app.UniformArrayCount);
            Assert.Equal (uarry1, app.GetUniformArray (0));
            Assert.Equal (uarry2, app.GetUniformArray (1));
        }

        [Fact]
        public void Test_RemoveUniformArray () {
            var app = new Appearance ();
            var uarry = new UniformArray ();

            app.AddUniformArray (uarry);
            app.RemoveUniformArray (uarry);

            Assert.Equal (0, app.UniformArrayCount);
        }

        [Fact]
        public void Test_UniformArrays () {
            var app = new Appearance ();
            var uarry1 = new UniformArray ();
            var uarry2 = new UniformArray ();
            var nod = new Node ();

            uarry1.Add ("Lynette Bishop", nod, () => nod.Alpha);
            uarry2.Add ("Minnie Bishop", nod, () => nod.Alpha);
            uarry2.Add ("Wilma Bishop", nod, () => nod.Alpha);

            app.AddUniformArray (uarry1);
            app.AddUniformArray (uarry2);

            var sum = app.UniformArrays.Sum (uarry => uarry.Count);

            Assert.Equal (3, sum);
        }


        /// <summary>
        /// サンプラーのセットのテスト
        /// </summary>
        [Fact]
        public void Test_AddSamper () {
            var app = new Appearance ();
            var tex = new Sampler (SamplerType.Texture2D);

            app.AddSampler (tex);

            Assert.Equal (1, app.SamplerCount);
            Assert.Equal (tex, app.GetSampler (0));
        }


        /// <summary>
        /// サンプラーの削除のテスト
        /// </summary>
        [Fact]
        public void Test_RemoveSampler () {
            var app = new Appearance ();
            var tex = new Sampler (SamplerType.Texture2D);

            app.AddSampler (tex);
            app.RemoveSampler (tex);

            Assert.Equal (0, app.SamplerCount);
        }

        [Fact]
        public void Test_GetSampler () {
            var app = new Appearance ();
            var sam0 = new Sampler (SamplerType.Texture2D);
            var sam1 = new Sampler (SamplerType.Texture2D);
            app.AddSampler (sam0);
            app.AddSampler (sam1);

            Assert.Equal (sam0, app.GetSampler (0));
            Assert.Equal (sam1, app.GetSampler (1));
        }

        [Fact]
        public void Test_GetSamplerIndex () {
            var app = new Appearance ();
            var sam0 = new Sampler (SamplerType.Texture2D);
            var sam1 = new Sampler (SamplerType.Texture2D);
            app.AddSampler (sam0);
            app.AddSampler (sam1);

            Assert.Equal (0, app.GetSamplerIndex (sam0));
            Assert.Equal (1, app.GetSamplerIndex (sam1));
        }


        /// <summary>
        /// サンプラーの列挙子のテスト
        /// </summary>
        /// <remarks>
        /// 列挙されるテクスチャーにnullは含まれない
        /// </remarks>
        [Fact]
        public void Test_Samplers () {
            var app = new Appearance ();
            var tex1 = new Sampler (SamplerType.Texture2D);
            var tex2 = new Sampler (SamplerType.Texture2D);

            app.AddSampler (tex1);
            app.AddSampler (tex2);
            var sum = app.Samplers.Sum (x => 1);

            Assert.Equal (2, sum);
        }

        [Fact]
        public void Test_References () {
            var app = new Appearance ();
            var mat = new Material ();
            var cmode = new CompositeMode ();
            //var pmode = new PolygonMode ();
            var psmode = new PointSpriteMode ();
            var unif = new UniformArray ();
            var sam = new Sampler (SamplerType.Texture2D);

            app.SetMaterial (mat);
            app.SetComositeMode (cmode);
            //app.SetPolygonMode (pmode);
            app.SetPointSpriteMode (psmode);
            app.AddUniformArray (unif);
            app.AddSampler (sam);
           
            var objs = app.References;

            Assert.Equal (5, objs.Count ());
            Assert.Equal (true, objs.All (x => x != null));
        }

        [Fact]
        public void Test_Find () {
            var app = new Appearance ();
            var mat = new Material ();
            var cmode = new CompositeMode ();
            var pmode = new PolygonMode ();
            var psmode = new PointSpriteMode ();
            var unif = new UniformArray ();
            var sam = new Sampler (SamplerType.Texture2D);

            app.SetMaterial (mat);
            app.SetComositeMode (cmode);
            app.SetPolygonMode (pmode);
            app.SetPointSpriteMode (psmode);
            app.AddUniformArray (unif);
            app.AddSampler (sam);
  
            mat.UserID = 101;
            cmode.UserID = 102;
            psmode.UserID = 103;
            unif.UserID = 104;
            sam.UserID = 105;
            app.UserID = 106;
            pmode.UserID = 107;

            Assert.Equal (mat, app.Find (101));
            Assert.Equal (cmode, app.Find (102));
            Assert.Equal (psmode, app.Find (103));
            Assert.Equal (unif, app.Find (104));
            Assert.Equal (sam, app.Find (105));
            Assert.Equal (app, app.Find (106));
            Assert.Equal (pmode, app.Find (107));
        }

    }
}
